//package com.fingard.util.sm2;
//
//import org.bouncycastle.asn1.*;
//import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
//import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
//import org.bouncycastle.crypto.params.ECPublicKeyParameters;
//import org.bouncycastle.math.ec.ECPoint;
//import org.bouncycastle.util.encoders.Base64;
//
//import java.io.ByteArrayInputStream;
//import java.io.ByteArrayOutputStream;
//import java.io.IOException;
//import java.math.BigInteger;
//import java.util.Enumeration;
//
//
//public class SM2Utils {
//
//    public static byte[] encrypt(byte[] publicKey, byte[] data) throws IOException {
//        if (publicKey == null || publicKey.length == 0) {
//            return null;
//        }
//
//        if (data == null || data.length == 0) {
//            return null;
//        }
//
//        byte[] source = new byte[data.length];
//        System.arraycopy(data, 0, source, 0, data.length);
//
//        Cipher cipher = new Cipher();
//        SM2 sm2 = SM2.Instance();
//
//        //处理密钥加04
//        byte[] formatedPubKey;
//        if (publicKey.length == 64){
//            //添加一字节标识，用于ECPoint解析
//            formatedPubKey = new byte[65];
//            formatedPubKey[0] = 0x04;
//            System.arraycopy(publicKey,0,formatedPubKey,1,publicKey.length);
//        }
//        else
//            formatedPubKey = publicKey;
//
//        ECPoint userKey = sm2.ecc_curve.decodePoint(formatedPubKey);
//
///*		ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);*/
//
//        ECPoint c1 = cipher.Init_enc(sm2, userKey);
//        cipher.Encrypt(source);
//        byte[] c3 = new byte[32];
//        cipher.Dofinal(c3);
//
//        //第一种加密
///*		// System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));
//		// System.out.println("C2 " + Util.byteToHex(source));
//		// System.out.println("C3 " + Util.byteToHex(c3));
//		// C1 C2 C3拼装成加密字串
//		String encryptdata = Util.encodeHexString(c1.getEncoded()) + Util.encodeHexString(source)
//				+ Util.encodeHexString(c3);
//		return Util.hexStringToBytes(encryptdata);*/
//
//        //第二种加密
//        DERInteger x = new DERInteger(c1.getX().toBigInteger());
//        DERInteger y = new DERInteger(c1.getY().toBigInteger());
//        DEROctetString derDig = new DEROctetString(c3);
//        DEROctetString derEnc = new DEROctetString(source);
//        ASN1EncodableVector v = new ASN1EncodableVector();
//        v.add(x);
//        v.add(y);
//        v.add(derDig);
//        v.add(derEnc);
//        DERSequence seq = new DERSequence(v);
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        DEROutputStream dos = new DEROutputStream(bos);
//        dos.writeObject(seq);
//        return bos.toByteArray();
//
//    }
//
//    public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException {
//        if (privateKey == null || privateKey.length == 0) {
//            return null;
//        }
//
//        if (encryptedData == null || encryptedData.length == 0) {
//            return null;
//        }
//
///*		//第一种解密
//		// 加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
//		String data = Util.byteToHex(encryptedData);
//		*//***
//         * 分解加密字串 （C1 = C1标志位2位 + C1实体部分128位 = 130） （C3 = C3实体部分64位 = 64） （C2 =
//         * encryptedData.length * 2 - C1长度 - C2长度）
//         *//*
//		byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
//		int c2Len = encryptedData.length - 97;
//		byte[] c2 = Util.hexToByte(data.substring(130, 130 + 2 * c2Len));
//		byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len));
//
//		SM2 sm2 = SM2.Instance();
//		BigInteger userD = new BigInteger(1, privateKey);
//
//		// 通过C1实体字节来生成ECPoint
//		ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
//		Cipher cipher = new Cipher();
//		cipher.Init_dec(userD, c1);
//		cipher.Decrypt(c2);
//		cipher.Dofinal(c3);
//		// 返回解密结果
//		return c2;*/
//
//        //第二种解密
//        byte[] enc = new byte[encryptedData.length];
//        System.arraycopy(encryptedData, 0, enc, 0, encryptedData.length);
//
//        SM2 sm2 = SM2.Instance();
//        BigInteger userD = new BigInteger(1, privateKey);
//
//        ByteArrayInputStream bis = new ByteArrayInputStream(enc);
//        ASN1InputStream dis = new ASN1InputStream(bis);
//
////        ASN1Primitive derObj = (ASN1Primitive) dis.readObject();
//        ASN1Sequence asn1 = (ASN1Sequence) dis.readObject();
//
//        Enumeration<ASN1Integer> e = asn1.getObjects();
//        BigInteger x = e.nextElement().getValue();
//        BigInteger y = e.nextElement().getValue();
//
//        ECPoint c1 = sm2.ecc_curve.createPoint(x, y, true);
//        Cipher cipher = new Cipher();
//        cipher.Init_dec(userD, c1);
//
//        DEROctetString data = (DEROctetString) asn1.getObjectAt(3);
//        enc =data.getOctets();
//        cipher.Decrypt(enc);
//        byte[] c3 = new byte[32];
//        cipher.Dofinal(c3);
//        return enc;
//    }
//
//
//
//    public static void main(String[] args) throws Exception {
//        Sm2KeyPair sm2KeyPair=generateKeyPair();
//
//        String plainText = "SM2加密解密签名测试！";
//        System.out.println("需要加密的字符串: "+plainText);
//        byte[] sourceData = plainText.getBytes();
//
//        // 国密规范测试私钥
//        String prik = "4A843981ED0527CD913CDAE286DDB00B21420203C6D602EAE48869071CA83207";
//
//        prik="74FC0ABE91E0280800807932D564F4B8471D45A71FF5E812E4892753CD3D1C6A";
//        prik=Util.getHexString(sm2KeyPair.getPriKey());
//
//        System.out.println("私钥: " + prik);
//
//
//        // 国密规范测试公钥
//        String pubk = "57789E7AB3713104AEC6CEE5510F1F507AAF21B40E81590EBBCEFF172032BFF2788ABA1ED915F0B8FC5037FC49C5E355CDA6D86FF7ACC0324DE0E5443A4D2DF5";
//        pubk="3E834C490C6F65C1AF542FD93F76E3B158F6725CAFAD6D307DD25D6BECD19D11CBE8FAAB394A19B1167373981149599CF2FC74836028A5ABDE0BFB4656EA7DA7";
//        pubk=Util.getHexString(sm2KeyPair.getPubKey());
//
//        System.out.println("公钥: " + pubk);
//
//
//        byte[] cipherText = SM2Utils.encrypt(Util.hexStringToBytes(pubk), sourceData);
//        System.out.println("加密后的文件: " +new String(Base64.encode(cipherText)));
//
//
//        String srcText = new String(SM2Utils.decrypt(Util.hexStringToBytes(prik), cipherText));
//        System.out.println("解密后的文件: " +srcText);
//
//
///*		//文件
//		System.out.println("SM2加密开始");
//		long start = System.currentTimeMillis();
//		byte[] fileByte = Util.getBytes("E:/ToTestworkspace/bouncycastle/Demo.xml");
//		byte[] encryptByte = SM2Utils.encrypt(Util.hexStringToBytes(pubk), fileByte);
//		Util.getFile(encryptByte, "E:/ToTestworkspace/bouncycastle/Demo2.xml");
//		long end = System.currentTimeMillis();
//		System.out.println("SM2加密生产文件完成，耗时："+(end-start)+"ms");
//
//		System.out.println("SM2解密开始");
//		long start1 = System.currentTimeMillis();
//		byte[] fileByte1 = Util.getBytes("E:/ToTestworkspace/bouncycastle/Demo2.xml");
//		byte[] decrypt = SM2Utils.decrypt(Util.hexStringToBytes(prik), fileByte1);
//		Util.getFile(decrypt, "E:/ToTestworkspace/bouncycastle/Demo3.xml");
//		long end2 = System.currentTimeMillis();
//		System.out.println("SM2解密生产文件完成，耗时："+(end2-start1) +"ms");*/
//
//    }
//
//
//    /**
//     * 获取公钥和私钥
//     * @return
//     */
//    public static Sm2KeyPair generateKeyPair(){
//        SM2 sm2 = SM2.Instance();
//        AsymmetricCipherKeyPair keypair = sm2.ecc_key_pair_generator.generateKeyPair();
//        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) keypair.getPrivate();
//        ECPublicKeyParameters ecpub = (ECPublicKeyParameters) keypair.getPublic();
//
//        //第一种方式
//        String priKey0 = ecpriv.getD().toString(16).toUpperCase();
//        String pubKey0 = ecpub.getQ().getX().toBigInteger().toString(16).toUpperCase()
//                + ecpub.getQ().getY().toBigInteger().toString(16).toUpperCase();
//        System.out.println("私钥: " + priKey0);
//        System.out.println("公钥: " + pubKey0);
//
//        //第一种方式
//        byte[] priKey = new byte[32];
//        byte[] pubKey = new byte[64];
//
//        byte[] bigNumArray = ecpriv.getD().toByteArray();
//        System.arraycopy(bigNumArray, bigNumArray[0]==0?1:0, priKey, 0, 32);
//        System.arraycopy(ecpub.getQ().getEncoded(), 1, pubKey, 0, 64);
//
//        System.out.println("私钥bigNumArray: " + Util.getHexString(bigNumArray));
//        System.out.println("私钥: " + Util.getHexString(priKey));
//        System.out.println("公钥: " + Util.getHexString(pubKey));
//
//        return new Sm2KeyPair(priKey, pubKey);
//    }
//
//}
